﻿using HenuAlbum.ControllerModels;
using HenuAlbum.DbContext;
using HenuAlbum.Identity;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using HenuAlbum.Models;
using Microsoft.EntityFrameworkCore;
using HenuAlbum.ResponseModels;
using System.Security.Claims;
using HenuAlbum.Utils;

namespace HenuAlbum.Controllers
{
    [ApiController]
    [Route("api/[controller]")]
    public class GroupAlbumController : ControllerBase
    {
        private readonly UserManager<User> _userManager;
        private readonly AppDbContext _appDbContext;

        public GroupAlbumController(UserManager<User> userManager, AppDbContext appDbContext)
        {
            _userManager = userManager;
            _appDbContext = appDbContext;
        }

        [HttpGet("Query")]
        public async Task<IActionResult> Query(int? collegeId, int? majorId, int? classId, int? gradeId, int limit = 20, int page = 1)
        {
            Tools.ResolveLimitAndPage(ref limit, ref page, 20, 100);
            var list = await _appDbContext.GroupAlbums
                    .AsNoTracking()
                    .Include(x => x.Class)
                    .ThenInclude(x => x.Major)
                    .ThenInclude(x => x.College)
                    .Include(x => x.Resources)
                    .Where(x => x.IsPublic &&
                            (classId == null ? true : x.ClassId == classId) &&
                            (gradeId == null ? true : x.Class.GradeId == gradeId) &&
                            (majorId == null ? true : x.Class.MajorId == majorId) &&
                            (collegeId == null ? true : x.Class.Major.CollegeId == collegeId))
                    .OrderBy(x => x.Id)
                    .Skip(limit * (page - 1))
                    .Take(limit)
                    .ToListAsync();
            return Ok(new ArrayResponse(list.Select(x =>
            new
            {
                x.Id,
                x.Title,
                x.Description,
                x.IsPublic,
                x.CreatorId,
                Coverid = x.Resources.FirstOrDefault()?.Id,
                LikeCount = _appDbContext.UserLikeAlbum.Count(y => y.AlbumId == x.Id),
                DownloadCount = x.Resources.Select(f => f.DownloadCount).FirstOrDefault()
            }).ToList()));
        }


        [HttpGet]
        public async Task<IActionResult> GetByClassId(int? classId, int limit = 20, int page = 1)
        {
            var data = await _appDbContext.GroupAlbums
                .AsNoTracking()
                .Include(x => x.Resources)
                .Include(x => x.Class)
                .Where(x => classId == null ? true : x.ClassId == classId)
                .ToListAsync();

            if (User.IsInRole("管理员"))
            {

            }
            else if (User.IsInRole("辅导员"))
            {
                var userIdStr = User.FindFirstValue(ClaimTypes.NameIdentifier);
                int userId = int.Parse(userIdStr);
                var user = await _appDbContext.Users
                   .Include(x => x.ManagedMajors)
                   .Where(x => x.Id == userId)
                   .FirstOrDefaultAsync();
                data.RemoveAll(x => !user.ManagedMajors.Any(t => t.Id == x.Class.MajorId));
            }
            else
            {
                data.RemoveAll(x => !x.IsPublic);
            }

            if (null == data)
            {
                return BadRequest(new IncorrectError("权限不够或相册不存在"));
            }

            Tools.ResolveLimitAndPage(ref limit, ref page, 20, 100);

            var result = data
                .OrderBy(x => x.Id)
                .Skip(limit * (page - 1))
                .Take(limit)
                .Select(x => new
                {
                    x.Id,
                    CoverId = x.Resources.FirstOrDefault()?.Id,
                    x.Title,
                    x.Description,
                    x.IsPublic,
                    LikeCount = _appDbContext.UserLikeAlbum.Count(y => y.AlbumId == x.Id),
                    DownloadCount = x.Resources.Select(f => f.DownloadCount).FirstOrDefault()
                }) ; 
            return Ok(new OkResponse() { Data = result });
        }

        [HttpPost("Add")]
        [Authorize(Roles = "管理员,辅导员")]
        public async Task<IActionResult> Add(AddGroupAlbumparam param)
        {
            var useridStr = User.FindFirstValue(ClaimTypes.NameIdentifier);
            int userid = int.Parse(useridStr);
            var user = await _appDbContext.Users
                .Include(x => x.ManagedMajors)
                .Where(x => x.Id == userid).FirstOrDefaultAsync();
            Class validclass = null;
            if (User.IsInRole("管理员"))
            {
                //班级的id必须在数据库中存在
                validclass = await _appDbContext.Classes.Where(x => x.Id == param.ClassId).FirstOrDefaultAsync();
                if (null == validclass)
                    return BadRequest(new IncorrectError("班级信息不存在!"));
            }
            else
            {
                //查到这个班级
                validclass = await _appDbContext.Classes
                                    .Include(x => x.Major)
                                    .Where(x => param.ClassId == x.Id).FirstOrDefaultAsync();
                //如果这个班级存在。而且在导员管理的专业中,do nothing
                if (null == validclass)
                {
                    return BadRequest(new IncorrectError("班级信息不存在！"));
                }

                if (!user.ManagedMajors.Any(x => x.Id == validclass.Major.Id))
                {
                    return BadRequest(new IncorrectError("权限不允许"));
                }

            }

            GroupAlbum groupAlbum = new GroupAlbum()
            {
                Title = param.Title,
                Description = param.Description,
                ClassId = validclass.Id,
                CreatorId = user.Id,
                IsPublic = param.IsPublic,
                CreateTime = DateTime.Now,
            };
            await _appDbContext.GroupAlbums.AddAsync(groupAlbum);
            await _appDbContext.SaveChangesAsync();
            return Ok(new OkResponse()
            {
                Data = new
                {
                    groupAlbum.Id,
                    groupAlbum.Title,
                    groupAlbum.Description,
                    groupAlbum.IsPublic,
                    groupAlbum.CreateTime
                }
            });

        }

        [HttpGet("{albumid:int}")]
        public async Task<IActionResult> Details(int albumid)
        {
            //这个接口应该任何人都能访问，获取相册
            var album = await _appDbContext.GroupAlbums
                .Include(x => x.Class)
                .Include(x => x.Class.Major)
                .AsNoTracking().Where(x => x.Id == albumid).FirstOrDefaultAsync();
            if (album == null)
            {
                return BadRequest(new NotExistsError("相册不存在"));
            }
            //如果是管理员或者相册时公开的，都可以访问
            if (album.IsPublic || User.IsInRole("管理员"))
            {

            }
            else
            {
                //学生和辅导员访问非公开相册的时候
                if (User.IsInRole("辅导员"))
                {
                    var useridstr = User.FindFirstValue(ClaimTypes.NameIdentifier);
                    int userid = int.Parse(useridstr);
                    var user = await _appDbContext.Users
                       .Include(x => x.ManagedMajors)
                       .Where(x => x.Id == userid)
                       .FirstOrDefaultAsync();
                    //辅导员不能获取不是他的班级的相册
                    if (user.ManagedMajors == null || !user.ManagedMajors.Any(x => x.Id == album.Class.Major.Id))
                    {
                        return BadRequest(new IncorrectError("权限不允许"));

                    }
                }
                else
                {
                    return BadRequest(new IncorrectError("权限不允许"));
                }

            }
            return Ok(new OkResponse()
            {
                Data = new
                {
                    album.Id,
                    album.Title,
                    album.Description,
                    album.IsPublic,
                    LikeCount = await _appDbContext.UserLikeAlbum.CountAsync(x => x.AlbumId == album.Id)
                }
            });


        }

        [HttpPost("{albumid:int}/Delete")]
        [Authorize(Roles = "管理员,辅导员")]
        public async Task<IActionResult> Delete(int albumid)
        {
            var album = await _appDbContext.GroupAlbums
                .Include(x => x.Class)
                .Include(x => x.Class.Major)
                .Where(x => x.Id == albumid).FirstOrDefaultAsync();
            if (album == null)
            {

                return BadRequest(new NotExistsError("相册不存在"));
            }
            if (User.IsInRole("管理员"))
            {

            }
            else
            {
                if (User.IsInRole("辅导员"))
                {
                    var useridstr = User.FindFirstValue(ClaimTypes.NameIdentifier);
                    int userid = int.Parse(useridstr);
                    var user = await _appDbContext.Users
                       .Include(x => x.ManagedMajors)
                       .Where(x => x.Id == userid)
                       .FirstOrDefaultAsync();

                    if (user.ManagedMajors == null || !user.ManagedMajors.Any(x => x.Id == album.Class.Major.Id))
                    {
                        return BadRequest(new IncorrectError("权限不允许"));

                    }
                }
                else
                {
                    return BadRequest(new IncorrectError("权限不允许"));
                }


            }
            _appDbContext.GroupAlbums.Remove(album);
            await _appDbContext.SaveChangesAsync();

            return Ok(new OkResponse());
        }

        [HttpPost("Update")]
        [Authorize(Roles = "管理员,辅导员")]
        public async Task<IActionResult> Update(UpdateGroupAlbumParam param)
        {
            var album = await _appDbContext.GroupAlbums
                .Include(x => x.Class)
                .Include(x => x.Class.Major)
                .Where(x => x.Id == param.id).FirstOrDefaultAsync();
            if (null == album)
            {
                return BadRequest(new NotExistsError("相册不存在"));
            }
            if (User.IsInRole("管理员"))
            {

            }
            else
            {
                if (User.IsInRole("辅导员"))
                {
                    var useridstr = User.FindFirstValue(ClaimTypes.NameIdentifier);
                    int userid = int.Parse(useridstr);
                    var user = await _appDbContext.Users
                       .Include(x => x.ManagedMajors)
                       .Where(x => x.Id == userid)
                       .FirstOrDefaultAsync();

                    if (user.ManagedMajors == null || !user.ManagedMajors.Any(x => x.Id == album.Class.Major.Id))
                    {
                        return BadRequest(new IncorrectError("权限不允许"));

                    }
                }
                else
                {
                    return BadRequest(new IncorrectError("权限不允许"));
                }


            }
            album.Description = param.Description;
            album.Title = param.Title;
            album.IsPublic = param.IsPublic;
            await _appDbContext.SaveChangesAsync();
            return Ok(new OkResponse());
        }
    }
}
